package com.pms.web;
import com.baomidou.mybatisplus.mapper.EntityWrapper;
import com.pms.entity.BaseUserInfo;
import com.pms.entity.FrontUser;
import com.pms.exception.R;
import com.pms.exception.RRException;
import com.pms.jwt.JwtAuthenticationResponse;
import com.pms.rpc.IUserService;
import com.pms.service.AuthService;
import com.pms.util.SmSUtile;
import com.pms.util.WebUtil;
import com.pms.validator.Assert;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.*;
import javax.servlet.http.HttpServletRequest;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
 * API 会员登录toeken
 */
@RestController
@RequestMapping("api/jwt")
public class ApiAuthController {
    Logger logger = LoggerFactory.getLogger(getClass());
    @Value("${gate.jwt.header}")
    private String tokenHeader;
    private BCryptPasswordEncoder encoder = new BCryptPasswordEncoder(12);
    @Autowired
    private AuthService authService;
    @Autowired
    private IUserService userService;
//    @Autowired
//    private ApiAuthService apiAuthService;
    @Autowired
    com.pms.cache.utils.RedisCacheUtil RedisCacheUtil;
    /**
     * 登录
     * token （由三部分组成 Header(请求头), Claims（要求）,Signature（签名））
     * @param
     * @return
     */
    @RequestMapping(value = "/token", method = RequestMethod.POST)
    public R createAuthenticationToken(
            String username,String password,String companyCode) {
        Assert.isNull(username,"账号不能为空");
        Assert.isNull(password,"密码不能为空");
        Assert.isNull(companyCode,"公司代码不能为空");
        BaseUserInfo info = userService.getByuseraccount(username,companyCode);
        if (null==info||null==info.getId()){throw  new RRException("输入信息有误，请重新输入",400);}
        if (2==info.getStatus()){ throw  new RRException("该账号已被停用，请联系管理员",400);}
        Map<String,Object> code=userService.getByCompany(info.getCompanyCode());
        if (null==code||null==code.get("id")){ throw  new RRException("公司信息不存在",400);}
        if (Integer.parseInt(code.get("status").toString())==2){ throw  new RRException("该账号所属系统已被禁用,请联系管理员",400);}
        if(encoder.matches(password,info.getPassword())){
            final String token = authService.login(info);
            FrontUser userInfo = authService.getApiUserInfo(token,companyCode);
            Map<String,Object> map= new HashMap<>();
            logger.info("login--token-  "+token);
            map.put("token",token);
            map.put("user",info);
            map.put("menu",userInfo.getMenus());
            map.put("elements",userInfo.getElements());
            return R.ok().put("data",map);
        }else {
            throw  new RRException("账号密码错误",400);
        }
    }

    /**
     * 验证码登录
     * @param username
     * @param companyCode
     * @return
     */
    @RequestMapping(value = "/verificationCodeLogin", method = RequestMethod.POST)
    public R verificationCodeLogin(String username,String companyCode){
        Assert.isNull(username,"手机号不能为空");
        Assert.isNull(companyCode,"公司代码不能为空");
        BaseUserInfo info = userService.getByuseraccount(username,companyCode);
        if (null==info){throw  new RRException("输入信息有误，请重新输入",400);}
        if (2==info.getStatus()){ throw  new RRException("该账号已被停用，请联系管理员",400);}
        Map<String,Object> code=userService.getByCompany(info.getCompanyCode());
        if (null==code||null==code.get("id")){ throw  new RRException("公司信息不存在",400);}
        if (Integer.parseInt(code.get("status").toString())==2){ throw  new RRException("该账号所属系统已被禁用,请联系管理员",400);}
           final String token = authService.login(info);
            FrontUser userInfo = authService.getApiUserInfo(token,companyCode);
            Map<String,Object> map= new HashMap<>();
            logger.info("login--token-  "+token);
            map.put("token",token);
            map.put("user",info);
            map.put("elements",userInfo.getElements());
            map.put("menu",userInfo.getMenus());
            return R.ok().put("data",map);
    }

    /**
     * 刷新token
     * @param request
     * @return
     */
    @RequestMapping(value = "/refresh", method = RequestMethod.POST)
    public ResponseEntity<?> refreshAndGetAuthenticationToken(
            HttpServletRequest request) {
        String token = request.getHeader(tokenHeader);
        String companyCode = request.getHeader("X-Code");
        String name = request.getHeader("X-Name");
        BaseUserInfo info = userService.getByuseraccount(name,companyCode);
        if (null==info){throw  new RRException("输入信息有误，请重新输入",400);}
        String refreshedToken = authService.refresh(token,info);
        if(refreshedToken == null) {
            return ResponseEntity.badRequest().body(null);
        } else {
            return ResponseEntity.ok(new JwtAuthenticationResponse(refreshedToken));
        }
    }


//    /**
//     * 验证token
//     * @param token
//     * @return
//     */
//    @RequestMapping(value = "/verify", method = RequestMethod.POST)
//    public ResponseEntity<?> verify(String token){
//        if(authService.validate(token))
//            return ResponseEntity.ok(true);
//        else
//            return ResponseEntity.status(401).body(false);
//    }

    /**
     * 退出清空token
     * @param token
     * @return
     */
    @RequestMapping(value = "/invalid", method = RequestMethod.POST)
    public R invalid(@RequestHeader("X-Token")String token){
        authService.invalid(token);
        return R.ok().put("data",true);
    }
    /**
     * 发送验证码(用于短信登录和忘记密码）
     * @param phone
     * @param type
     * @return
     */
    @RequestMapping(value="/shortMessageLogin",method = RequestMethod.POST)
    public R shortMessageLogin(String phone,String type){
        Assert.isNull(phone,"手机号码不能为空");
        Assert.isNull(type,"type类型不能为空");
        if (type.equals("2") || type.equals("3")){
            boolean isphone= WebUtil.isMobileNO(phone.trim());//手机号正则验证
            if(isphone == false){ return R.error("手机号码格式不正确，请你从新输入！");}
            int user=userService.getListByPhone(phone);
            if (user==0){return  R.error(400,"该账号尚未被注册，请重新输入账号");}
            String   smsCode = SmSUtile.sendSms(phone,Integer.parseInt(type), null);
            if (smsCode.equals("error")){ return R.error(400,"对不起！该手机号一分钟不能超过一条，请稍等一分钟后再试！");}
            if (StringUtils.isNotBlank(smsCode)) {
                if (Integer.valueOf(smsCode) <= 0) {
                    smsCode = "0";
                }
                RedisCacheUtil.saveAndUpdate(phone + "API_PMS_ShortMessageLogin",smsCode,10);
                return R.ok().put("codes",smsCode);
            } else {
                smsCode = "0";
            }
        }else {
            return  R.error(400,"type参数类型错误");
        }
        return R.ok();
    }
    /**
     * 验证码登录匹对和忘记密码匹对
     * @param phone
     * @param code
     * @return
     */
    @RequestMapping(value = "/VerificationLogin",method = RequestMethod.POST)
    public R VerificationLogin(String phone, String code) {
        Assert.isNull(code,"验证码不能为空");
        Assert.isNull(phone,"手机号码不能为空");
        boolean isphone= WebUtil.isMobileNO(phone.trim());//手机号正则验证
        if(isphone == false){ return R.error("手机号码格式不正确，请从新输入！");}
        Object SMSCode= RedisCacheUtil.getVlue(phone + "API_PMS_ShortMessageLogin");
        if(SMSCode==null){ return R.error("输入验证码已失效！"); }
        if (code != null && code.equals(SMSCode.toString())) {
            RedisCacheUtil.clearByKey(phone + "API_PMS_ShortMessageLogin");
            List<Map<String,Object>> obj=userService.selectByCompanyCode(phone);
            return R.ok().put("data",obj);
        }else{
            return R.error("输入验证码不正确！");
        }
    }

    /**
     * 忘记密码
     * @param phone
     * @param passWord
     * @param companyCode
     * @return
     */
    @RequestMapping(value = "/resetPassword",method = RequestMethod.POST)
    public R retrievePassword(String phone, String passWord,String companyCode) {
        Assert.isNull(phone, "手机号不能为空");
        Assert.isNull(passWord, "密码不能为空");
        Assert.isNull(companyCode,"公司编码不能为空");
        boolean isphone= WebUtil.isMobileNO(phone.trim());//手机号正则验证
        if(isphone == false){ return R.error("手机号码格式不正确，请你从新输入！");}
        userService.updataPhoneCompanyCodePassWord(phone,companyCode,passWord);
        return R.ok();
    }



}
